package com.xiaohong.pay.AliPay.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.xiaohong.order.feign.OrderFeign;
import com.xiaohong.order.feign.OrderItemFeign;
import com.xiaohong.order.pojo.Order;
import com.xiaohong.order.pojo.OrderItem;
import com.xiaohong.pay.AliPay.interceptor.TokenRequestInterceptor;
import entity.Result;
import entity.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xiaohong
 * @Description
 * @date 2020/12/24 0024 16:42
 */
@RestController
@RequestMapping("/aliPay")
public class AliPayController {


    @Value("${zfb.app_id}")
    private String app_id;

    @Value("${zfb.gatewayUrl}")
    private String gatewayUrl;

    @Value("${zfb.merchant_private_key}")
    private String merchant_private_key;

    @Value("${zfb.alipay_public_key}")
    private String alipay_public_key;

    @Value("${zfb.sign_type}")
    private String sign_type;

    @Value("${zfb.charset}")
    private String charset;

    @Value("${zfb.return_url}")
    private String return_url;

    @Value("${zfb.notify_url}")
    private String notify_url;

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private OrderItemFeign orderItemFeign;

    /**
     * 修改订单状态
     * @param httpServletRequest
     * @param sn
     * @param id
     * @return
     */
    @GetMapping("/query/{sn}/{id}")
    public Result<OrderItem> zfb_query(HttpServletRequest httpServletRequest,
                            @PathVariable(value = "sn") String sn,
                            @PathVariable(value = "id") String id) {

        //获取token
        String token = httpServletRequest.getHeader("Authorization");
        TokenRequestInterceptor.token = token;

        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id,merchant_private_key, "json",charset, alipay_public_key, sign_type);

        //设置请求参数
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();


        Map<String, Object> map = new HashMap<>();

        map.put("out_trade_no",sn);

        alipayRequest.setBizContent(JSON.toJSONString(map));

        //请求
        String result = null;
        try {
            result = alipayClient.execute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        //输出
        System.out.println(result);

        // 判断是否响应成功
        if (result != null){
            // 转换为map
            Map<String,Object> resultMap = JSON.parseObject(result, Map.class);
            // 获取订单结果
            Map<String,String> response = (Map<String, String>) resultMap.get("alipay_trade_query_response");

            String code = response.get("code"); //网关返回码
            String msg = response.get("msg"); //网关返回码描述
            String sub_code = response.get("sub_code"); // 业务返回码（失败时才有）
            String sub_msg = response.get("sub_msg"); // 业务返回码描述(失败时才有)
            String buyer_logon_id = response.get("buyer_logon_id"); //买家在支付宝的用户id
            String buyer_pay_amount = response.get("buyer_pay_amount"); // 买家实付金额，单位为元，两位小数。
            String buyer_user_id = response.get("buyer_user_id"); // 买家支付宝账号
            String buyer_user_type = response.get("buyer_user_type"); // 买家用户类型。CORPORATE:企业用户；PRIVATE:个人用户。
            String invoice_amount = response.get("invoice_amount"); // 交易中用户支付的可开具发票的金额
            String out_trade_no = response.get("out_trade_no"); // 商家订单号
            String point_amount = response.get("point_amount"); // 积分支付的金额，单位为元，两位小数。
            String receipt_amount = response.get("receipt_amount"); // 实收金额，单位为元，两位小数。
            String total_amount = response.get("total_amount"); //交易的订单金额，单位为元，两位小数
            String trade_no = response.get("trade_no"); // 支付宝交易号
            //交易状态
            //WAIT_BUYER_PAY（交易创建，等待买家付款）、TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、
            // TRADE_SUCCESS（交易支付成功）、TRADE_FINISHED（交易结束，不可退款）
            String trade_status = response.get("trade_status");

            for (String s : response.keySet()) {
                System.out.println(s+":   "+response.get(s));
            }

            // 判断响应状态
            if (msg.equals("Success") && code.equals("10000")){
                // 判断响应结果
                if ("TRADE_SUCCESS".equals(trade_status)){
                    //交易成功
                    changStatus(id,1);
                }else if ("WAIT_BUYER_PAY".equals(trade_status)){
                    //交易创建，等待买家付款
                    changStatus(id,0);
                }else if("TRADE_CLOSED".equals(trade_status)){
                    //未付款交易超时关闭，或支付完成后全额退款
                    changStatus(id,5);
                }else {
                    //交易结束，不可退款
                    changStatus(id,5);
                }
            }else {
                // 交易状态查询失败或交易未创建
//                changStatus(out_trade_no,0);
            }
        }

        // 设置退款查询请求
        AlipayTradeFastpayRefundQueryRequest refundQueryRequest = new AlipayTradeFastpayRefundQueryRequest();

        // 请求退款接口时，传入的退款请求号
        map.put("out_request_no",id);
        refundQueryRequest.setBizContent(JSON.toJSONString(map));

        String refundQueryResult = null;
        try {
            refundQueryResult = alipayClient.execute(refundQueryRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        //输出
        System.out.println(refundQueryResult);

        if (refundQueryRequest != null){
            // 转换为map
            Map<String,Object> refundResultMap = JSON.parseObject(refundQueryResult, Map.class);
            // 获取退款查询结果
            Map<String,String> refundResponse = (Map<String, String>) refundResultMap.get("alipay_trade_fastpay_refund_query_response");

            String code = refundResponse.get("code"); //网关返回码
            String msg = refundResponse.get("msg"); //网关返回码描述
            String out_request_no = refundResponse.get("out_request_no"); // 本笔退款对应的退款请求号
            String out_trade_no = refundResponse.get("out_trade_no"); // 创建交易传入的商户订单号
            String buyer_logon_id = refundResponse.get("buyer_logon_id"); //买家在支付宝的用户id
            String refund_amount = refundResponse.get("refund_amount"); // 本次退款请求，对应的退款金额
            String total_amount = refundResponse.get("total_amount"); // 该笔退款所对应的交易的订单金额
            String trade_no = refundResponse.get("trade_no"); // 支付宝交易号

            // 判断响应状态
            if (msg.equals("Success") && code.equals("10000") && refund_amount != null){
                // 退款成功
                changStatus(id,3);
            }

        }

//        OrderItem orderItem = new OrderItem();
//        OrderItem data = orderItemFeign.findById(id).getData();

        // 还原token
        TokenRequestInterceptor.token = null;

        return new Result<OrderItem>(true, StatusCode.OK,"订单状态更新成功");
    }


    /**
     * 修改订单状态
     * @param orderItemId
     */
    public void changStatus(String orderItemId,Integer status) {
//        Order order = orderFeign.findById(orderId).getData();
//        if (order != null && order.getPayStatus() != 3){
//            Order order1 = new Order();
//            order1.setPayStatus(status);
//            orderFeign.update(order1,order.getId());
//        }

        OrderItem orderItem1 = new OrderItem();
        orderItem1.setStatus(status);
        orderItemFeign.update(orderItem1,orderItemId);

//        OrderItem orderItem = new OrderItem();
//        orderItem.setOrderId(orderId);
//        List<OrderItem> list = orderItemFeign.findList(orderItem).getData();
//        if (list != null && list.size() > 0){
//            for (OrderItem item : list) {
//                if (item.getStatus() != 3){
//
//                }
//            }
//        }

    }


    @PutMapping("/refund/{orderItemId}")
    public Result<String> refund(@PathVariable("orderItemId") String orderItemId,HttpServletRequest httpServletRequest) {

        //获取token
        String token = httpServletRequest.getHeader("Authorization");
        TokenRequestInterceptor.token = token;

        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type);

        //设置请求参数
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();

        String result = null;

        // 查询订单
        OrderItem orderItem = orderItemFeign.findById(orderItemId).getData();
        if (orderItem != null){
            Order order = orderFeign.findById(orderItem.getOrderId()).getData();
            if (order != null){
                Map<String, Object> map = new HashMap<>();
                //支付宝交易号
                map.put("trade_no",order.getTransactionId());
                //需要退款的金额，该金额不能大于订单金额，必填
                map.put("refund_amount",orderItem.getPayMoney());
                //退款的原因说明
                map.put("refund_reason","我就是要退！");
                //标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传
                map.put("out_request_no",orderItem.getId());
                alipayRequest.setBizContent(JSON.toJSONString(map));
                //请求
                try {
                    result  = alipayClient.execute(alipayRequest).getBody();
                } catch (AlipayApiException e) {
                    e.printStackTrace();
                }
                // 判断响应结果
                // 转换为map
                Map<String,Object> resultMap = JSON.parseObject(result, Map.class);

                // 获取订单结果
                Map<String,String> response = (Map<String, String>) resultMap.get("alipay_trade_refund_response");


                String code = response.get("code"); //网关返回码
                String msg = response.get("msg"); //网关返回码描述
                String sub_code = response.get("sub_code"); // 业务返回码（失败时才有）
                String sub_msg = response.get("sub_msg"); // 业务返回码描述(失败时才有)
                String buyer_logon_id = response.get("buyer_logon_id"); //买家在支付宝的用户id
                String fund_change = response.get("fund_change"); // 本次退款是否发生了资金变化
                String buyer_user_id = response.get("buyer_user_id"); // 买家支付宝账号
                String out_trade_no = response.get("out_trade_no"); // 商家订单号
                String trade_no = response.get("trade_no"); // 支付宝交易号
                String refund_fee = response.get("refund_fee"); //退款总金额
                String send_back_fee = response.get("send_back_fee");

                for (String s : response.keySet()) {
                    System.out.println(s+":   "+response.get(s));
                }

                result = sub_msg;

                // 判断响应状态
                if (msg.equals("Success") && code.equals("10000") && "Y".equals(fund_change)){
                    // 修改订单状态
                    OrderItem orderItem1 = new OrderItem();
                    orderItem1.setStatus(3);
                    orderItemFeign.update(orderItem1,orderItem.getId());
                    return new Result<String>(true,StatusCode.OK,"退款成功",result);
                }else if ("N".equals(fund_change)){
                    // 已退款
                    // 修改订单状态
                    OrderItem orderItem1 = new OrderItem();
                    orderItem1.setStatus(3);
                    orderItemFeign.update(orderItem1,orderItem.getId());
                    return new Result<String>(true,StatusCode.ERROR,"已退款！");
                }
                else {
                    // 修改订单状态
                    OrderItem orderItem1 = new OrderItem();
                    orderItem1.setStatus(4);
                    orderItemFeign.update(orderItem1,orderItem.getId());
                    return new Result<String>(true,StatusCode.ERROR,result);
                }
            }
        }

        // 还原token
        TokenRequestInterceptor.token = null;

        return new Result<String>(true,StatusCode.OK,result);
    }

}
